package com.itcoon.cloud.framework.utils;


import com.itcoon.cloud.framework.config.TemporalPatternConfig;
import com.itcoon.cloud.framework.properties.TemporalPatternConfigProperties;
import com.itcoon.cloud.framework.temporal.AbstractConverter;

import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.temporal.Temporal;
import java.time.temporal.UnsupportedTemporalTypeException;
import java.util.Arrays;

public class TemporalConvertUtils {

    public static <T extends Temporal> T getInstance(Class<T> clazz){
        if(ZonedDateTime.class.equals(clazz)){
            return (T)ZonedDateTime.now();
        }
        if(LocalDateTime.class.equals(clazz)){
            return (T)LocalDateTime.now();
        }
        if(LocalDate.class.equals(clazz)){
            return (T)LocalDate.now();
        }
        throw new UnsupportedTemporalTypeException("Rejected type"+clazz.getName());
    }

    public static <S extends Serializable, T extends Temporal> TemporalPatternConfigProperties.TemporalSerialization<S, T> getTemporalSerialization(Class<T> temporalType) {
        TemporalPatternConfigProperties properties = SpringUtils.getBean(TemporalPatternConfigProperties.class);
        TemporalPatternConfigProperties.TemporalSerialization<?, ?>[] temporalSerializations = properties.getTemporalSerializations();
        return (TemporalPatternConfigProperties.TemporalSerialization<S, T>) Arrays.stream(temporalSerializations).filter(t -> t.getTemporalType().equals(temporalType)).findFirst().orElse(null);
    }

    public static <S extends Serializable, T extends Temporal> S format(T temporal){
        TemporalPatternConfigProperties.TemporalSerialization<S, T> temporalSerialization = TemporalConvertUtils.getTemporalSerialization((Class<T>) temporal.getClass());
        AbstractConverter<S, T> converter =  TemporalPatternConfig.getConverter(temporalSerialization.getSerialType(), temporal.getClass());
        return converter.format(temporal);
    }

    public static <S extends Serializable, T extends Temporal> T parse(S source, Class<T> temporalType){
        AbstractConverter<S, T> converter =  TemporalPatternConfig.getConverter((Class<S>) source.getClass(), temporalType);
        return converter.parse(source);
    }
}
